<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>

<HEAD>
  <TITLE>overview of glean internals</TITLE>
  <META NAME="description" CONTENT="glean internal classes and objects">
  <META NAME="author" CONTENT="Allen Akin">
  <LINK REV="made" HREF="mailto:akin@pobox.com">
</HEAD>

<BODY bgcolor=#FFFFFF topmargin="10" bottommargin="10" leftmargin="10"
  rightmargin="10" marginheight="0" marginwidth="0">

<H1>Overview of <I>glean</I> internals</H1>

<H2>Directory structure</H2>

<P>
Starting at <KBD>$GLEAN_ROOT</KBD>, you'll see <KBD>bin</KBD>,
<KBD>include</KBD>, and <KBD>lib</KBD> directories.
These are initially empty, and are filled by the Makefile in
<KBD>src</KBD>.

<P>
<KBD>$GLEAN_ROOT</KBD> also contains documentation in <KBD>doc</KBD>,
common Makefile templates in <KBD>make</KBD>, sample result files in
<KBD>results</KBD>, and source code in <KBD>src</KBD>.
The Makefile templates are particularly interesting, since they
automate nearly all of the process of defining Makefiles.

<P>
cd into <KBD>src</KBD>, and take a look around.
The main Makefile resides here.  There are also subdirectories for
<I>glean</I> itself (<KBD>glean</KBD>), a wrapper for OpenGL header
files that covers up some Windows-specific problems (<KBD>glh</KBD>),
libraries that are used by multiple tools (<KBD>libs</KBD>), and
code for tools like <I>showvis</I> (<KBD>tools</KBD>).  The Makefile
ensures that everything in the subdirectories is built in the correct
order.

<H2>Libraries</H2>

<P>
There are several libraries providing services that you may want when
you start writing tests.  These particular libraries are of sufficiently
general usefulness that they're broken out into separate directories.
(As we'll see later, some other services are local to the <KBD>glean</KBD>
subdirectory.)
<UL TYPE=DISC>
  <LI>
    <B>dsurf</B>
    <BR>
    This library provides a portable interface to drawing surface
    configuration information (pixel format descriptors under Windows,
    and extended X11 Visuals under X).  It also provides the filtering
    capability that's used by <I>showvis</I> and <I>glean</I> to
    select configurations that match particular criteria.
  <LI>
    <B>image</B>
    <BR>
    The basic abstraction provided by this library is an in-memory
    image structure that maps almost directly onto the image format
    used by OpenGL.  The library also offers utilities that read and
    write TIFF files, tools to convert image data to a common format,
    and convenience routines for invoking OpenGL operations like
    reading and drawing images.  Finally, there is a "registration"
    utility that compares two images and attempts to align one on top
    of the other in the position at which the images are most similar.
  <LI>
    <B>lex</B>
    <BR>
    This is a simple lexical analyzer.  <B>libdsurf</B> uses it when
    parsing drawing surface configuration criteria, and when constructing
    a drawing surface configuration from a canonical description stored
    in a results file.
  <LI>
    <B>rand</B>
    <BR>
    This set of classes provides uniform random values in several different
    ranges and formats, in an OS-independent fashion.  (This allows results
    generated by <I>glean</I> on one OS to be compared to results on the same
    hardware running under another OS.)  It's based on a linear congruential
    generator discussed in Knuth Vol. 2 and Numerical Recipes (2nd ed.).
  <LI>
    <B>stats</B>
    <BR>
    These classes generate simple statistical measures (min, max, mean,
    standard deviation, etc.).
  <LI>
    <B>timer</B>
    <BR>
    This class provides timing services for benchmarking.  It's capable of
    calibrating measurement overhead, repeating benchmarks until a target
    runtime is achieved, etc.
</UL>

<H2><I>glean</I> itself</H2>

<P>
<I>glean</I> consists of a relatively simple main program, a set of
classes providing commonly-needed services, and the tests themselves.

<P>
The main program essentially just parses command-line options, creates
the test environment (see below) and invokes each test in turn.  The
list of tests is generated automatically by test class constructors,
so there's no need to maintain one independently.  It should be fairly
straightforward to replace the current main program with a graphical
front-end, if anyone cares to do so.

<P>
The main service classes are as follows:

<UL TYPE=DISC>
  <LI>
    <B>Options</B>
    <BR>
    This class collects all option information (the verbosity level,
    names of the test results databases, etc.) in one place.  Doing
    so allows option setting to be separated from option interpretation.
  <LI>
    <B>Environment</B>
    <BR>
    This class encapsulates information about the test environment:
    the options, an output stream for the test log, the window system,
    etc.  It is passed as an argument to each test.
  <LI>
    <B>WindowSystem</B>
    <BR>
    This class abstracts information about the window system, so that
    most <I>glean</I> tests need not know the system under which they're
    running.  Its main task is to maintain lists of drawing surface
    configurations, drawing surfaces, and OpenGL rendering contexts.
    However, it does expose window-system-specific data (such as the
    X11 Display pointer) so that window-system-specific tests can be
    written.  (Such tests must use conditional compilation to protect
    references to non-portable function calls and data structures,
    though.)
  <LI>
    <B>DrawingSurface</B> and <B>Window</B>
    <BR>
    A drawing surface is a canvas on which OpenGL rendering can take
    place.  Each drawing surface has a configuration that specifies
    the buffers (color, depth, stencil, etc.) associated with the
    surface.
    The prototypical drawing surface is the window, which adds size
    information and buffer-swap capability that's used by most tests.
    Eventually we will need to add more drawing surfaces to <I>glean</I>,
    for example, the PBuffers supported under GLX version 1.3.
  <LI>
    <B>RenderingContext</B>
    <BR>
    A rendering context encapsulates all OpenGL state information
    (except for the contents of the drawing surface).  In general,
    in order to render, you must create a drawing surface, create
    a rendering context, and then bind the two (using a service
    provided by the <B>WindowSystem</B> class).  Then you can use
    ordinary OpenGL commands freely.
</UL>

<P>
A few general utilities are also available:
<UL TYPE=DISC>
  <LI>
    <B>useScreenCoords()</B> (<KBD>glutils.h</KBD>)
    <BR>
    Sets up the modelview and projection matrices so that OpenGL
    object coordinates correspond directly to screen pixel
    coordinates.  (Note:  The origin of the coordinate system is
    at the lower left corner of the window.)  This is convenient
    for most tests of rasterization operations.
  <LI>
    <B>RandomMesh2D</B> (<KBD>geomutil.h</KBD>)
    <BR>
    Creates a 2D array of points that fit within a given bounding
    rectangle, but are displaced by random amounts from the lattice
    points within it.  This is especially useful for benchmarking,
    because it yields randomly sized and oriented triangles whose
    average area is nevertheless accurately known.
</UL>

<P>
To create a new test, you need do little more than create a new
.cpp file in the <KBD>glean</KBD> subdirectory.  (The Makefile
will handle its dependencies and build it automatically.)
All tests are derived from the base class <B>Test</B>.  For truly
new types of tests you'll need to derive a new class, but for many
common types of tests you can start by copying a test that already
exists.  Here are some examples:

<UL TYPE=DISC>
  <LI>
    <B>BasicTest</B> (<KBD>tbasic.cpp</KBD>)
    <BR>
    This is a good outline for any
    simple test that runs in one window with one rendering context,
    generating a result for each drawing surface configuration that
    meets specified criteria.  If your test is of this type, you may
    be able to copy <KBD>tbasic.cpp</KBD> and modify just the functions
    <B>runOne()</B>, <B>compareOne()</B>, <B>put()</B>, and <B>get()</B>.
    It may be instructive to compare <KBD>tbasic.cpp</KBD> with
    <KBD>tgetstr.cpp</KBD>, which is derived in just that way.
  <LI>
    <B>TexBindPerf</B> (<KBD>tchgperf.cpp</KBD>)
    <BR>
    This test demonstrates how to measure performance, by benchmarking
    texture binding time.  It's a bit more complicated than
    <B>BasicTest</B>, but the structure is basically the same, and
    most of the work is concentrated in the four functions mentioned
    above.
  <LI>
    <B>RGBTriStripTest</B> (<KBD>trgbtris.cpp</KBD>)
    <BR>
    This shows how to save and compare TIFF images.  While it's not a
    good idea to make too many tests dependent on image comparisons
    (because they're not particularly robust), there are cases like
    regression testing where image comparison may be a good approach.
</UL>

<P>
That's pretty much all there is to it.  The <I>glean</I> framework
provides most of the mechanisms needed to develop simple tests.
Now it's time to create a good set of tests and thereby make a new
tool that's valuable to the entire OpenGL community.


<HR>
<SMALL>
  <UL TYPE=DISC>
    <LI> <A HREF="index.html"><I>glean</I> home</A>
    <LI> <A HREF="whatis.html">What is <I>glean</I>?</A>
    <LI> <A HREF="build.html">How do I build <I>glean</I>?</A>
    <LI> <A HREF="run.html">How do I run <I>glean</I>?</A>
    <LI> <A HREF="next.html">Where do we go from here?</A>
      <UL TYPE=CIRCLE>
        <LI> <A HREF="newtest.html">Adding new tests</A>
	<LI> <A HREF="newfeat.html">Adding new infrastructure features</A>
	<LI> <A HREF="overview.html">Overview of <I>glean</I> internals</A>
        <LI> <A HREF="repo.html">Creating a repository of results</A>
        <LI> <A HREF="port.html">Porting <I>glean</I></A>
        <LI> <A HREF="cleanup.html">Cleaning up loose ends</A>
      </UL>
    <LI> <A HREF="changes.html">What has changed recently?</A>
  </UL>
</SMALL>

</BODY>
</HTML>
